/*
 * 
 */

package com.memorytech.starchive.httpservice;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.protocol.HTTP;
import org.json.JSONObject;

import android.os.AsyncTask;
import android.util.Log;

import com.memorytech.starchive.httpservice.AbstractMap.SimpleEntry;
import com.memorytech.starchive.xmlparser.ParserDataHelper;

/**
 * The Class HttpClient.
 * 
 * @author Tam-LT
 */
public class HttpClientHelper extends Observable implements IService {

    /** The http uri request. */
    private HttpUriRequest httpUriRequest;

    /** The http client helper. */
    private volatile static HttpClientHelper httpClientHelper;
    private static final String POST_CONTENT_TYPE = "application/x-www-form-urlencoded";

    /** The time out get data (mili seconds). */
    public static int TIME_OUT_GET_DATA = 25000;

    /** The time out connection(mili seconds). */
    public static int TIME_OUT_CONNECTION = 20000;

    /**
     * Gets the single instance of HttpClientHelper.
     * 
     * @return single instance of HttpClientHelper
     */
    public static HttpClientHelper getInstance() {
        if (httpClientHelper == null) {
            synchronized (HttpClientHelper.class) {
                if (httpClientHelper == null) {
                    httpClientHelper = new HttpClientHelper();
                }

            }

        }
        return httpClientHelper;
    }

    /*
     * (non-Javadoc)
     * @see com.aris.barcode.HttpService.IService#login(java.lang.String,
     * java.lang.String, java.lang.String)
     */
    @Override
    public void login(String username, String password, String serverAddress) {
        // TODO Auto-generated method stub
        String url = "";
        httpUriRequest = new HttpPost(url);
        ((HttpPost) httpUriRequest).setHeader(Params.CONTENT_TYPE, POST_CONTENT_TYPE);

        JSONObject jsonObject = new JSONObject();
        try {
            /*
             * We add all params that method need to excute logging in method
             * here
             */jsonObject.put("", "");

        } catch (Exception e) {
            // TODO: handle exception
            Log.e("TamLe", e.toString());
        }
        setParams(jsonObject);
        new HttpTask(httpUriRequest).execute(Methods.login);

    }

    /*
     * (non-Javadoc)
     * @see com.aris.barcode.HttpService.IService#search(java.lang.String)
     */
    @Override
    public void search(String barcode) {
        // TODO Auto-generated method stub
        String url = "";
        httpUriRequest = new HttpGet(url);
        new HttpTask(httpUriRequest).execute(Methods.search);

    }

    /*
     * (non-Javadoc)
     * @see
     * com.aris.barcode.HttpService.IService#getBarcodeInfo(java.lang.String,
     * boolean, boolean, java.lang.String, java.lang.String, int, int)
     */
    @Override
    public void getBarcodeInfo(String barcodeName, boolean fList, boolean tList, String fileName,
            String fileType, int searchFrom, int searchTo) {
        // TODO Auto-generated method stub
        String url = "";
        httpUriRequest = new HttpGet(url);
        new HttpTask(httpUriRequest).execute(Methods.getBarcodeInfo);
    }

    /*
     * (non-Javadoc)
     * @see
     * com.aris.barcode.HttpService.IService#advancedSearch(java.lang.String,
     * java.lang.String, java.lang.String,
     * com.aris.barcode.HttpService.IService.Criteria)
     */
    @Override
    public void advancedSearch(String tapeName, String fileName, String fileType, Criteria criteria) {
        // TODO Auto-generated method stub
        String url = "";
        httpUriRequest = new HttpGet(url);
        new HttpTask(httpUriRequest).execute(Methods.advancedSearch);
    }

    /**
     * Sets the params.
     * 
     * @param jsonObj the new params
     */
    private void setParams(JSONObject jsonObj) {
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair(Params.PARAMS, jsonObj.toString()));
        UrlEncodedFormEntity entity = null;
        try {
            entity = new UrlEncodedFormEntity(params, HTTP.UTF_8);
        } catch (UnsupportedEncodingException e) {
            Log.e("Tamle", e.toString());
        }

        ((HttpPost) httpUriRequest).setEntity(entity);
    }

    /**
     * The Class HttpTask.
     */
    private class HttpTask extends AsyncTask<Methods, Void, List<Object>> {

        /*
         * (non-Javadoc)
         * @see android.os.AsyncTask#onCancelled()
         */
        @Override
        protected void onCancelled() {
            // TODO Auto-generated method stub
            super.onCancelled();
        }

        /*
         * (non-Javadoc)
         * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
         */
        @Override
        protected void onPostExecute(List<Object> result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
            setChanged();
            SimpleEntry<IService.Methods, List<Object>> ret = new SimpleEntry<IService.Methods, List<Object>>(
                    methodId, result);
            notifyObservers(ret);
        }

        /*
         * (non-Javadoc)
         * @see android.os.AsyncTask#onPreExecute()
         */
        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            super.onPreExecute();
        }

        /*
         * (non-Javadoc)
         * @see android.os.AsyncTask#onProgressUpdate(Progress[])
         */
        @Override
        protected void onProgressUpdate(Void... values) {
            // TODO Auto-generated method stub
            super.onProgressUpdate(values);
        }

        /** The method id. */
        private Methods methodId;

        /** The http uri request. */
        private HttpUriRequest a_ttpUriRequest;

        /**
         * Instantiates a new http task.
         * 
         * @param httpUriRequest the http uri request
         */
        public HttpTask(HttpUriRequest httpUriRequest) {
            a_ttpUriRequest = httpUriRequest;

            /*
             * In some cases we need to add some info to request's header and
             * send it to server team for some reasons(EX: count how many
             * request to server) a_ttpUriRequest.addHeader(name, value);
             * a_ttpUriRequest.addHeader(name, value);
             * a_ttpUriRequest.addHeader(name, value);
             * a_ttpUriRequest.addHeader(name, value);
             * a_ttpUriRequest.addHeader(name, value);
             */

        }

        /*
         * (non-Javadoc)
         * @see android.os.AsyncTask#doInBackground(Params[])
         */
        @Override
        protected List<Object> doInBackground(Methods... params) {
            // TODO Auto-generated method stub
            methodId = params[0];
            return perform(methodId);
        }

        /**
         * Perform.
         * 
         * @param methodId the method id
         * @return the list
         */
        private List<Object> perform(Methods methodId) {
            // TODO Auto-generated method stub
            HttpClient httpClient = new DefaultHttpClient();
            HttpConnectionParams.setTcpNoDelay(httpClient.getParams(), true);
            HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), TIME_OUT_CONNECTION);
            HttpConnectionParams.setSoTimeout(httpClient.getParams(), TIME_OUT_GET_DATA);

            List<Object> result = null;

            try {
                HttpResponse response = httpClient.execute(a_ttpUriRequest);
                final int statusCode = response.getStatusLine().getStatusCode();
                // check status code is OK or not
                if (statusCode != HttpStatus.SC_OK) {
                    return result;
                }
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    try {
                        result = ParserDataHelper.getInstance()
                                .parse(entity.getContent(), methodId);

                    } finally {

                    }

                }
            } catch (Exception e) {
                // TODO: handle exception
            }

            return result;
        }

    }
}
